home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows News 2010 Summer - Disc 1
/
WN_Ete2010_CD1.iso
/
Onglet5
/
Weezo
/
Weezo setup.exe
/
{code_appDir}
/
www
/
includes
/
proxyFunctions.php
< prev
next >
Wrap
PHP Script
|
2010-05-19
|
52KB
|
1,321 lines
<?php
/**
* Proxy functions
*
* PHP version 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category NA
* @package NA
* @author Nicolas Bruley / Peer 2 World <contact@weezo.net>
* @copyright 2005-2009 Nicolas Bruley / Peer 2 World
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id:$
* @link http://www.weezo.net
* @since File available since Release 1.0.9
*/
$processedLinkAttributes=array('href', 'src', 'action');
$processedJSAttributes=array('onclick', 'onmouseover', 'onmouseout', 'ondblclick', 'onload', 'onresize', 'onabort', 'onblur', 'onchange', 'onerror', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup','onmousedown', 'onmouseup', 'onmousemove', 'onreset', 'onselect', 'onsubmit', 'onunload');
/**
* @desc Set proxy options from resource session data
*
*/
function proxySetOptions(){
if(!isset($_ENV['options']['noReferer'])) {
$_ENV['options']['noReferer']=false;
if(cfRGetVar('optionNoReferer')) $_ENV['options']['noReferer']=true;
}
if(!isset($_ENV['options']['noPopups'])) {
$_ENV['options']['noPopups']=false;
if(cfRGetVar('optionNoPopups')) $_ENV['options']['noPopups']=true;
}
if(!isset($_ENV['options']['noScripts'])) {
$_ENV['options']['noScripts']=false;
if(cfRGetVar('optionNoScripts')) $_ENV['options']['noScripts']=true;
}
if(!isset($_ENV['options']['noCookies'])) {
$_ENV['options']['noCookies']=false;
if(cfRGetVar('optionNoCookies')) $_ENV['options']['noCookies']=true;
}
}
/**
* Decode gzip compressed page
*
* @param string $data : compressed data
* @return string : uncompressed data
*/
function gzdecode ($data) {
$flags = ord(substr($data, 3, 1));
$headerlen = 10;
$extralen = 0;
$filenamelen = 0;
if ($flags & 4) {
$extralen = unpack('v' ,substr($data, 10, 2));
$extralen = $extralen[1];
$headerlen += 2 + $extralen;
}
if ($flags & 8) // Filename
$headerlen = strpos($data, chr(0), $headerlen) + 1;
if ($flags & 16) // Comment
$headerlen = strpos($data, chr(0), $headerlen) + 1;
if ($flags & 2) // CRC at end of file
$headerlen += 2;
$unpacked = gzinflate(substr($data, $headerlen));
if ($unpacked === FALSE)
$unpacked = $data;
return $unpacked;
}
/**
* @desc Send headers received from website to browser
*
* @param string $fullStatus: HTTP response status (HTTP/1.x: XXX xxxxx)
* @param array $headers: array of headers
* @param boolean $justDisplay : set to true to display headers instead of sending them
*/
function proxySendHeadersToBrowser($fullStatus, $headers,$justDisplay=false){
// Process headers
if(isset($headers['location'])) $headers['location']=proxyEncodeUrlPHP(proxyURLSetAbsolute($headers['location']));
if(isset($headers['content-location'])) $headers['content-location']=proxyEncodeUrlPHP(proxyURLSetAbsolute($headers['content-location']));
if(isset($headers['refresh'])&&strpos($headers['refresh'],'URL='))
$headers['refresh']=substr($headers['refresh'],0,strpos($headers['refresh'],'URL=')+4).proxyEncodeUrlPHP(proxyURLSetAbsolute(substr($headers['refresh'],strpos($headers['refresh'],'URL=')+4)));
// Remove cookies
unset($headers['set-cookie']);
unset($headers['warning']);
unset($headers['content-md5']);
if(!$justDisplay) {
// HTTP response header
header($fullStatus);
// Other headers
foreach ($headers as $key=>$value) header(ucfirst($key).': '.$value);
}
else {
echo '<div style="background:#FEE;border:1px solid #DDD;padding:5px;margin-bottom:1em">';
echo $decodedURL.'<br>';
echo $fullStatus.'<br>';
foreach ($headers as $key=>$value) echo (ucfirst($key).': '.$value)."<br>\n";
echo '</div>';
}
}
/**
* Turns a relative or absolute URL into absolute URL, from $_ENV['siteURLHost'].$_ENV['siteURLPath'] URL
*
* @param string $url
* @return string: absolute URL
*/
function proxyURLSetAbsolute($url){
if(!$url) return $_ENV['siteURLHost'].$_ENV['siteURLPath'];
if(substr($url,0,2)=='//') $url=$_ENV['siteURLScheme'].':'.$url;
if(substr(strtolower($url),0,7)!='http://' && substr(strtolower($url),0,8)!='https://'){
if($url[0]!='/') {
// If HTML doc has a <base> node, use its href attribute as base path
if(isset($_ENV['baseHref']) && $_ENV['baseHref']) $url=$_ENV['baseHref'].$url;
else $url=$_ENV['siteURLPath'].'/'.$url;
}
$count=1;
// Replace /youpi/../ by /
while($count) $url=preg_replace("/\/[^\/]+\/[.]{2}/","",$url,-1,$count);
// Remove remaining /../ (but there should be none)
$url=str_replace('/../','/',$url);
// Add site host if needed
if(substr(strtolower($url),0,4)!='http') $url=$_ENV['siteURLHost'].$url;
}
return $url;
}
/**
* @desc Encode an URL
*
* @param string $url: absolute URL to encode
* @return string: encoded URL
*/
function proxyEncodeUrlPHP($url,$tagName=false){
if(substr(strtolower($url),0,7)!='http://' && substr(strtolower($url),0,8)!='https://') $url='http://'.$url;
//$enc=str_replace('/','_',str_replace('=','-',base64_encode((strpos($url,'?'))?substr($url,0,strpos($url,'?')):$url)));
$enc=str_replace('/','_',str_replace('=','-',base64_encode($url)));
if(strtolower($tagName=='script')) $mimeType='js/';
elseif(strtolower($tagName=='style')) $mimeType='css/';
else $mimeType='';
return $_ENV['baseURLProxy'].chunk_split($enc,254,'/').'/eourl/'.$mimeType.'a'.basename(((strpos($url,'?'))?substr($url,0,strpos($url,'?')):$url));
}
/**
* @desc Decode encoded URL from SERVER URI
*
* @param string $url: URL to decode
* @return string: decoded URL
*/
function proxyDecodeUrlPHP($url=false){
if($url) $url=substr($url,strpos($url,'/',9));
$encoded=substr((($url)?$url:$_SERVER['REQUEST_URI']),strlen(dirname($_SERVER['PHP_SELF']))+1);
if(strpos($encoded,'?')) $get=substr($encoded,strpos($encoded,'?')); else $get='';
if($get=='?') $get='';
$encoded=substr($encoded,0,strpos($encoded,'/eourl/'));
$encoded=str_replace('/','',$encoded);
//cfDbg('Decoded:'.base64_decode(str_replace('_','/',str_replace('-','=',$encoded))).$get.' --- enc:'.$encoded,1);
// If no new GET parameter passed, use original encoded URL
if(!$get) return base64_decode(str_replace('_','/',str_replace('-','=',$encoded)));
// If a GET parameter is passed, remove get parameter b64 encoded in original url
$b64Clear=base64_decode(str_replace('_','/',str_replace('-','=',$encoded)));
if(strpos($b64Clear,'?')) $b64Clear=substr($b64Clear,0,strpos($b64Clear,'?'));
return $b64Clear.$get;
}
/**
* @desc Process href, src, onclick, onmouse... attributes
*
* @param string $attrValue: attribute value
* @return string: processed attribute
*/
function processHRef($attrValue, $tagName=false){
$attrValue=trim($attrValue);
if($attrValue=='#') return '#';
// Javascript
if(strtolower(substr($attrValue,0,11)=='javascript:')) return 'javascript:'.proxyProcessJavascript(substr($attrValue,11));
// inline data ("data:")
if(strtolower(substr($attrValue,0,5)=='data:')) {
$data=trim(substr($attrValue,5));
// not javascript: don't touch
if(substr($data,0,15)!='text/javascript') return $attrValue;
// inline javascript code
$data=rawurldecode(substr($data,16));
if(substr($data,0,7)=='base64,') $data=base64_decode(substr($data,7));
// protect javascript code
return 'data:text/javascript;base64,'.rawurlencode(base64_encode(proxyProcessJavascript($data)));
}
// Link
return proxyEncodeUrlPHP(proxyURLSetAbsolute($attrValue),$tagName);
}
/**
* @desc Process a node's attributes
*
* @param HTML node: $node
*/
function proxyProcessNode(&$node){
global $processedLinkAttributes;
global $processedJSAttributes;
$nodeName=$node->nodeName;
// 'href', 'src', 'action'
foreach ($processedLinkAttributes as $attr){
if(strtolower($nodeName)=='link' && $node->hasAttribute('rel') && $node->getAttribute('rel')=='stylesheet') $nodeName='style';
if($node->hasAttribute($attr)) $node->setAttribute($attr,processHRef($node->getAttribute($attr),$nodeName));
}
// 'onclick', 'onmouseover', 'onmouseout' ...
foreach ($processedJSAttributes as $attr)
if($node->hasAttribute($attr)) $node->setAttribute($attr,proxyProcessJavascript($node->getAttribute($attr)));
if($node->hasAttribute('style')) $node->setAttribute('style',proxyProcessCSS($node->getAttribute('style')));
foreach ($node->childNodes as $cn) if($cn->nodeType==XML_ELEMENT_NODE) proxyProcessNode($cn);
}
function proxyProtectJavascriptCB($matches){
//cfDbg($matches[3],1);
//if(!$matches[3]) $matches[4]=$matches[3].'=>'.$matches[1].(($matches[3])?'b64'.base64_encode($matches[3]):'').'</script';
//if(!$matches[3]) cfDbg($matches,1);
//cfDbg($matches[3].'=>'.$matches[1].(($matches[3])?'b64'.base64_encode($matches[3]):'').'</script',1);
return $matches[1].(($matches[3])?'b64'.base64_encode($matches[3]):'').'</script';
}
function proxyUnprotectJavascriptCB($matches){
//cfDbg(base64_decode($matches[1]),1);
return '>'.base64_decode($matches[1]).'<';
}
/**
* @desc url() replacement preg_match_callback function
*/
// ActiveXObject("Microsoft.XMLHTTP") and XMLHttpRequest() open method replacement
function proxyProcessJavascriptCB1($matches){
return '.open('.$matches[1].',proxyEncodeURL('.$matches[2].')'.((isset($matches[3]))?$matches[3]:'').')';
}
// Replaces "siteHref.href ="
function proxyProcessJavascriptCB2($matches){return 'proxyDocumentLocationNode.value='.$matches[1];}
// Replaces (document.)location by siteHref, and document.cookie by proxyGetCookie
function proxyProcessJavascriptCB3($matches){
if(isset($matches[4])) $matches[4]=trim($matches[4]);
// If quoted, don't transform
if(trim($matches[2])=='.' || $matches[4]=='"' || $matches[4]=='"') return $matches[0];
if($matches[0][0]=='"' || $matches[0][1]=="'") return $matches[0];
if(trim($matches[3])=='location'){
if(strpos($matches[0],'document')!==false) return substr($matches[0],0,strpos($matches[0],'document')).'siteHref'.$matches[4];
elseif(strpos($matches[0],'self')!==false) return substr($matches[0],0,strpos($matches[0],'self')).'siteHref'.$matches[4];
return $matches[2].'siteHref'.$matches[4];
}
elseif(trim($matches[3])=='cookie' && strpos($matches[0],'document')!==false){
return substr($matches[0],0,strpos($matches[0],'document')).'proxyGetCookie()'.$matches[4];
}
return $matches[0];
}
// (document.)location "set" replacement
function proxyProcessJavascriptCB4($matches){
if(substr($matches[2],0,8)=='document'||substr($matches[2],0,4)=='self') return 'proxyDocumentLocationNode.value=';
if(substr(trim($matches[2]),-1)=='.') return $matches[0];
return $matches[2].'proxyDocumentLocationNode.value=';
}
// setTimeout, setInterval & eval replacement
function proxyProcessJavascriptCB5($matches){
return 'proxy'.ucfirst($matches[0]);
return '.'.$matches[1].'=proxyEncodeURL('.$matches[2].')';
}
// x = document; replacement
function proxyProtectJavascriptCB6($matches){return '=proxyDoc'.$matches[1];}
/**
* @desc Process javascript text
*
* @param string $script
* @return string
*/
function proxyProcessJavascript($script){
/* $inquote value :
0 : out of quotes
1 : single quote '
2 : double quote "
3 : simple comment //
4 : passge comment * /
*/
// Remove javascript option
if(isset($_ENV['options']['noScripts']) && $_ENV['options']['noScripts']) return '';
// ActiveXObject("Microsoft.XMLHTTP") and XMLHttpRequest() open method replacement
$script=preg_replace_callback("/\.\s*open\s*\(\s*(\"post\"|\"get\")\s*,([^)\,]*)(,([^)]*)){0,1}\)/i", "proxyProcessJavascriptCB1", $script);
// top and parent replacement
$script=str_replace('top.','',str_replace('parent.','',$script));
// Remove cookie actions if set in options
if($_ENV['options']['noCookies'])
$script=preg_replace('/(document\s*\.){1,1}cookie\s*=/','proxyFoo=',$script);
// window.open(x) => window.open(proxyEncodeURL(x))
$pattern="/window\s*\.\s*open\s*\(/";
$new='';
while(preg_match($pattern, $script, $matches, PREG_OFFSET_CAPTURE)){
$stack=''; $lastStack=''; $inquote=false;
$sp=$matches[0][1]+strlen($matches[0][0]);
$new.=substr($script,0,$sp);
$script=substr($script,$sp);
$sp=0; $prevc='';
if($script[0]=='=') continue;
$strlen=strlen($script);
while($sp<$strlen){
$c=$script[$sp];
if(!$inquote){
if(!$stack && ($c==')' || $c==',')) break;
else{
if(($c==')'&&$lastStack=='(')||($c=='}'&&$lastStack=='{')||($c==']'&&$lastStack=='['))
{$stack=substr($stack,0,strlen($stack)-1); $lastStack=substr($stack,-1);}
elseif($c=='('||$c=='{'||$c=='['){$lastStack=$c;$stack.=$c;}
elseif($c=="'") $inquote=1;
elseif($c=='"') $inquote=2;
elseif($c=='/' && $prevc=='/') $inquote=3;
elseif($c=='*' && $prevc=='/') $inquote=4;
}
}
else{
if((($inquote==1&&$c=="'")||($inquote==2&&$c=='"'))&&$prevc!='\\') $inquote=0;
elseif($inquote==3 && (($c=="\n" || $c=="\r") || ($c=="/" && $prevc=='/'))) $inquote=0;
elseif($inquote==4 && $c=="/" && $prevc=='*') $inquote=0;
}
$prevc=$c;
$sp++;
}
if($sp) $new.='proxyEncodeURL('.substr($script,0,$sp).')';
$script=substr($script,$sp);
}
$script=$new.$script;
// action, src, innerHTML, location, URL and href += method replacement
$pattern="/(\.\s*src|\.\s*action|\.\s*href|\.\s*URL|\.\s*innerHTML|\s*location)\s*(\+)\s*=/";
$del=";{}\n\r+-=*!:?|&/><](";
$pos=0;
$prevc='';
while(preg_match($pattern, $script, $matches, PREG_OFFSET_CAPTURE,$pos)){
$sp=$matches[0][1];
$complete=false;
$stack=''; $lastStack=''; $inquote=false;
while($sp>=0){
$c=$script[$sp];
if(!$inquote){
// Try to guess if carriage return is an end of line
if(!$stack && $c=="\n"||$c=="\r"){
$lc=substr(trim(substr($script,0,$sp)),-1);
$del2="\r\n ";
$sp2=$sp+1;$lsc=strlen($script);while($sp2<$lsc && strpos($del2,$script[$sp2])!==false) $sp2++;
// End of script => end of instruction
if($sp2==$lsc) break;
$del2="+-&|!.(";
// Instruction finished
if(strpos($del2,$lc)===false && strpos($del2,$script[$sp2])===false) break;
}
if(!$stack && strpos($del,$c)!==false) break;
else{
if(($c=='('&&$lastStack==')')||($c=='['&&$lastStack==']'))
{$stack=substr($stack,0,strlen($stack)-1); $lastStack=substr($stack,-1);}
elseif($c==')'||$c==']'){
if($prevc!='.') break;
$lastStack=$c;$stack.=$c;
}
elseif($c=="'") $inquote=1;
elseif($c=='"') $inquote=2;
}
}
else{
if((($inquote==1&&$c=="'")||($inquote==2&&$c=='"'))) $inquote=0;
}
if($c!=' ' && $c!=chr(11)) $prevc=$c;
$sp--;
}
$found=substr($script,$sp+1,$matches[1][1]+strlen($matches[1][0])-$sp-1);
$pos=$matches[2][1]; $script[$pos]=' ';
$script=substr($script,0,$matches[0][1]+strlen($matches[0][0])).$found.'+'.substr($script,$matches[0][1]+strlen($matches[0][0]));
}
// domain/URL replacement
$del=";{}\n\r+-=*!:?|&/><,](";
$pos=0;
$prevc='';
while(($sp=strpos($script,'.domain',$pos)) || ($sp=strpos($script,'. domain',$pos)) || ($sp=strpos($script,'.URL',$pos)) || ($sp=strpos($script,'. URL',$pos))){
$complete=false;
$stack=''; $lastStack=''; $inquote=false;
if(substr($script,$sp,3)=='. d') $domainL=8;
elseif(substr($script,$sp,2)=='.d') $domainL=7;
elseif(substr($script,$sp,2)=='.U') $domainL=4;
else $domainL=5;
$pos=$sp+$domainL;
// Verify that it's actually "domain" or "URL"
if(strlen($script)==$pos-1 || preg_match("/[\w]/",$script[$pos]) || $script[$pos]=='.') continue;
// reverse browse $script for start of variable
while($sp>=0){
$c=$script[$sp];
if(!$inquote){
// Try to guess if carriage return is an end of line
if(!$stack && $c=="\n"||$c=="\r"){
$lc=substr(trim(substr($script,0,$sp)),-1);
$del2="\r\n ";
$sp2=$sp+1;$lsc=strlen($script);while($sp2<$lsc && strpos($del2,$script[$sp2])!==false) $sp2++;
// End of script => end of instruction
if($sp2==$lsc) break;
$del2="+-&|!.(";
// Instruction finished
if(strpos($del2,$lc)===false && strpos($del2,$script[$sp2])===false) break;
}
if(!$stack && strpos($del,$c)!==false) break;
else{
if(($c=='('&&$lastStack==')')||($c=='['&&$lastStack==']'))
{$stack=substr($stack,0,strlen($stack)-1); $lastStack=substr($stack,-1);}
elseif($c==')'||$c==']'){
if($prevc!='.') break;
$lastStack=$c;$stack.=$c;
}
elseif($c=="'") $inquote=1;
elseif($c=='"') $inquote=2;
}
}
else{
if((($inquote==1&&$c=="'")||($inquote==2&&$c=='"'))) $inquote=0;
}
if($c!=' ' && $c!=chr(11)) $prevc=$c;
$sp--;
}
if(substr($script,$sp,3)=='. d' || substr($script,$sp,2)=='.d')
$script=substr($script,0,$sp+1).'siteHref.domain'.substr($script,$pos);
else
$script=substr($script,0,$sp+1).'siteHref.href'.substr($script,$pos);
$pos=$sp+11;
}
// action, src, innerHTML and href method replacement
// include document.cookie replacement too
$pattern="/(\.\s*src|\.\s*action|\.\s*href|\.\s*innerHTML|[^.]\s*document\s*\.\s*cookie)\s*=/";
$new='';
while(preg_match($pattern, $script, $matches, PREG_OFFSET_CAPTURE)){
// Remove 1st non-matching chars of document.cookie
if(strpos($matches[0][0],'document')){
$offset=strpos($matches[0][0],'doc');
$matches[0][0]=substr($matches[0][0],strpos($matches[0][0],'doc'));$matches[0][1]+=$offset;
$matches[1][0]=substr($matches[1][0],strpos($matches[1][0],'doc'));$matches[1][1]+=$offset;
}
$stack=''; $lastStack=''; $inquote=false;
$sp=$matches[0][1]+strlen($matches[0][0]);
$new.=substr($script,0,$sp);
//if($matches[0][0]=='.src =') cfDbg($script);
//cfVarDump($matches,1);
$script=substr($script,$sp);
$sp=0; $prevc='';
if($script[0]=='=') continue; // Do not process "=="
$strlen=strlen($script);
while($sp<$strlen){
$c=$script[$sp];
if(!$inquote){
// Try to guess if carriage return is an end of instruction
if(!$stack && $c=="\n"||$c=="\r"){
$lc=substr(trim(substr($script,0,$sp)),-1);
$del="\r\n ";
$sp2=$sp+1;$lsc=strlen($script);while($sp2<$lsc && strpos($del,$script[$sp2])!==false) $sp2++;
// End of script => end of instruction
if($sp2==$lsc) break;
$del="+-&|!.(";
// Instruction finished
if(strpos($del,$lc)===false && strpos($del,$script[$sp2])===false) break;
}
if(!$stack && ($c==';'||$c==')'||$c=='}'||$c==']')) break;
else{
if(($c==')'&&$lastStack=='(')||($c=='}'&&$lastStack=='{')||($c==']'&&$lastStack=='['))
{$stack=substr($stack,0,strlen($stack)-1); $lastStack=substr($stack,-1);}
elseif($c=='('||$c=='{'||$c=='['){$lastStack=$c;$stack.=$c;}
elseif($c=="'") $inquote=1;
elseif($c=='"') $inquote=2;
elseif($c=='/' && $prevc=='/') $inquote=3;
elseif($c=='*' && $prevc=='/') $inquote=4;
}
}
else{
if((($inquote==1&&$c=="'")||($inquote==2&&$c=='"'))&&$prevc!='\\') $inquote=0;
elseif($inquote==3 && (($c=="\n" || $c=="\r") || ($c=="/" && $prevc=='/'))) $inquote=0;
elseif($inquote==4 && $c=="/" && $prevc=='*') $inquote=0;
}
$prevc=$c;
$sp++;
}
// innerHTML : use proxyJSProcessHTML (HTML encoding) function
if($sp && stripos($matches[1][0],'innerhtml')) $new.='proxyJSProcessHTML('.substr($script,0,$sp).')';
// Set cookie
elseif($sp && stripos($matches[1][0],'cookie'))
$new=substr($new,0,strlen($new)-strlen($matches[0][0])).'proxySetCookie('.substr($script,0,$sp).')';
// src/action/href/location : use proxyEncodeURL (URL encoding) function
elseif($sp) $new.='proxyEncodeURL('.substr($script,0,$sp).')';
$script=substr($script,$sp);
}
$script=$new.$script;
// Document.write replacement
$pattern="/(document\s*.\s*write(ln){0,1}\s*\()/";
$new='';
while(preg_match($pattern, $script, $matches, PREG_OFFSET_CAPTURE)){
$stack=''; $lastStack=''; $inquote=false;
$sp=$matches[0][1]+strlen($matches[0][0]);
$new.=substr($script,0,$matches[0][1]).((isset($matches[2]))?'proxyDocumentWriteln(':'proxyDocumentWrite(');
$script=substr($script,$sp);
$sp=0; $prevc='';$strlen=strlen($script);
while($sp<$strlen){
$c=$script[$sp];
if(!$inquote){
if($c=="\n"||$c=='\r') $script[$sp]=' ';
// End of instruction found
if(!$stack && ($c==';'||$c=="\r"||$c==')'||$c=='}'||$c==']')) {
// Check if instruction is followed by another document.write
$sp2=$sp+1;
while ($sp2<$strlen && ($script[$sp2]=="\n" || $script[$sp2]=="\r" || $script[$sp2]==';' || $script[$sp2]==' ' || $script[$sp2]=="\t")) $sp2++;
// if so...
if(substr($script,$sp2,8)=='document' && preg_match('/^document\s*\.\s*write(ln){0,1}\s*\(/',substr($script,$sp2),$matches)){
// Join both document.write by spaces and a +
while($sp<$sp2+strlen($matches[0])-1) $script[$sp++]=' ';
$script[$sp]='+';
}
else break;
}
else{
if(($c==')'&&$lastStack=='(')||($c=='}'&&$lastStack=='{')||($c==']'&&$lastStack=='['))
{$stack=substr($stack,0,strlen($stack)-1); $lastStack=substr($stack,-1);}
elseif($c=='('||$c=='{'||$c=='['){$lastStack=$c;$stack.=$c;}
elseif($c=="'") $inquote=1;
elseif($c=='"') $inquote=2;
elseif($c=='/' && $prevc=='/') $inquote=3;
elseif($c=='*' && $prevc=='/') $inquote=4;
}
}
else{
if((($inquote==1&&$c=="'")||($inquote==2&&$c=='"'))&&$prevc!='\\') $inquote=0;
elseif($inquote==3 && (($c=="\n" || $c=="\r") || ($c=="/" && $prevc=='/'))) $inquote=0;
elseif($inquote==4 && $c=="/" && $prevc=='*') $inquote=0;
}
$prevc=$c;
$sp++;
}
if($sp) $new.=substr($script,0,$sp);
$script=substr($script,$sp);
}
$script=$new.$script;
// (document/self.)location & cookie "get" replacement
$script=preg_replace_callback("/(([^.\sa-zA-Z]\s*document\s*\.\s*|[^.\sa-zA-Z]\s*self\s*\.\s*|\.\s*|\W)(location|cookie))(\s*[^=\s]|\s*[=]{2})/", 'proxyProcessJavascriptCB3', $script);
// replaces "siteHref.href ="
$script=preg_replace_callback("/siteHref\.href\s*=([^=])/", 'proxyProcessJavascriptCB2', $script);
// (document/self.)location "set" replacement
$script=preg_replace_callback("/((document\s*\.\s*|self\s*\.\s*|\W)location(\s*\.\s*href){0,1})(\s*=)/",'proxyProcessJavascriptCB4', $script);
// setTimeout, setInterval & eval replacement
$script=preg_replace_callback("/(setTimeout|setInterval|eval)\s*\(/", 'proxyProcessJavascriptCB5', $script);
// x = document; replacement (unused)
$script=preg_replace_callback("/[=]\s*document(\s*[^\.\s])/", "proxyProtectJavascriptCB6", $script);
return $script;
}
/**
* @desc url() replacement preg_match_callback functions
*/
function proxyProcessCSSMatch($matches) {return $matches[1].processHRef($matches[2]).$matches[3];}
function proxyProcessCSSMatch2($matches){
$url=trim($matches[2]);
$sep="'";
if($url[0]=='"' || $url[0]=="'") {
$sep=$url[0];
$url=substr($url,1,strlen($url)-2);
}
return $matches[1].$sep.processHRef($url).$sep.$matches[3];
}
/**
* @desc process CSS style section
*
* @param string $style : CSS text
* @return string processed CSS
*/
function proxyProcessCSS($style){
$style=preg_replace_callback("/(@import\s*['|\"])(.*?)(['|\"])/i", 'proxyProcessCSSMatch',$style);
return preg_replace_callback("/(url\s*[(])(.*?)([)])/i", 'proxyProcessCSSMatch2',$style);
}
/**
* Process HTML document, echo result
*
* @param string $body : HTML code (whole doc, not only <body>)
*/
function proxyProcessHTML($body,$contentType=false){
cfChronoAddPoint('start');
// Workaround : DOM parser bug on <script> tags including other tags (in document.write for example) => base64 encode content
//$body=preg_replace_callback("/(<\s*script\s*([^>]*)>)((.|\n|\r)+?)<\/script/i", "proxyProtectJavascriptCB", $body);
$pos=0;$pos3=0;
while(($pos=stripos($body,'<script',$pos))){
if(($pos3=strpos($body,'>',$pos+6)) && ($pos2=stripos($body,'</script',$pos3))){
$body=substr($body,0,$pos3+1).'b64'.base64_encode(substr($body,$pos3+1,$pos2-$pos3-1)).substr($body,$pos2);
$pos=$pos2;
}
else break;
}
/**
* Try to find encoding before loading HTML in dom document
* (workaround for ill-detected encoding if <title> is before <meta HTTP-EQUIV="content-type" ...>
*/
// Used to state wether a <title> has been found before <meta> defining encoding (meaning that things will have to be fixed
// if encoding passed into headers, consider that it has to be fixed
$titleBeforeMeta=true;
// If no charset passed into headers, try to find it into meta data
if(!$contentType || stripos($contentType,'charset')===false){
$dom = new DOMDocument();
@$dom->loadHTML($body);
if($dom->getElementsByTagName('head')->length){
$titleBeforeMeta=false;
$child=$dom->getElementsByTagName('head')->item(0)->firstChild;
while ($child) {
// <title> found
if($child->nodeName=='title') $titleBeforeMeta=true;
elseif($child->nodeName=='meta' && $child->hasAttribute("http-equiv") && $child->hasAttribute("content")
&& $child->getAttribute("http-equiv")=='content-type') {
// Charset found !
if(stripos($child->getAttribute("content"),'charset')!==false){
$contentType=$child->getAttribute("content");
break;
}
}
$child=$child->nextSibling;
}
}
}
// If a charset has been passed into headers or has been found in <meta>
// If !$titleBeforeMeta, no need to re-parse document
if($titleBeforeMeta && $contentType && stripos($contentType,'charset')!==false){
// If document has a <head>, append content-type meta right at the begining
if(($pos=stripos($body,'<head'))!==false){
while ($body[$pos]!='>' && $pos<99999) $pos++;
$body=substr($body,0,$pos+1).'<meta HTTP-EQUIV="content-type" CONTENT="'.$contentType.'">'.substr($body,$pos+1);
}
else $body='<meta HTTP-EQUIV="content-type" CONTENT="'.$contentType.'">'.$body;
// Load DOM
$dom = new DOMDocument();
@$dom->loadHTML($body);
}
//cfDbg($dom->getElementsByTagName('head')->length,1);
// Recursively process href, src, on... attributes
// Check for <base> node
$_ENV['baseHref']=false;
foreach($dom->getElementsByTagName('base') as $v){
if($v->hasAttribute('href')) {
$_ENV['baseHref']=$v->getAttribute('href');
// Set trailing slash
if(substr($_ENV['baseHref'],-1)!='/') $_ENV['baseHref'].='/';
// Make baseHref absolute
if(substr(strtolower($_ENV['baseHref']),0,4)!='http'){
while(substr($_ENV['baseHref'],0,1)=='/') $_ENV['baseHref']=substr($_ENV['baseHref'],1);
$_ENV['baseHref']=$_ENV['siteURLHost'].$_ENV['baseHref'];
}
// Remove href attribute so base is not utilised anymore (shouldn't happend anyway as URLs are all set absolutes)
$v->removeAttribute('href');
break;
}
}
// Process href, src, onclick, onmouse... nodes attributes
foreach ($dom->childNodes as $cn) if($cn->nodeType==XML_ELEMENT_NODE) proxyProcessNode($cn);
// Process meta http-equiv / content = refresh
foreach ($dom->getElementsByTagName('meta') as $v) if($v->hasAttribute('http-equiv') && $v->hasAttribute('content') && strtolower($v->getAttribute('http-equiv'))=='refresh') {
if(strpos($v->getAttribute('content'),';')) {
$refreshURL=trim(substr($v->getAttribute('content'),strpos($v->getAttribute('content'),';')+1));
if(!$refreshURL) continue;
if(substr($refreshURL,0,4)=='URL=') $refreshURL=substr($refreshURL,4);
$v->setAttribute('content',substr($v->getAttribute('content'),0,strpos($v->getAttribute('content'),';')+1).'URL='.proxyEncodeUrlPHP($refreshURL));
}
}
// Process javascript nodes (assume all scripts are javascript...)
foreach ($dom->getElementsByTagName('script') as $v) {
if($v->nodeValue) {
if(substr($v->nodeValue,0,3)=='b64')
$v->nodeValue='b64'.base64_encode(proxyProcessJavascript(base64_decode(substr($v->nodeValue,3))));
else
$v->nodeValue='b64'.base64_encode(proxyProcessJavascript($v->nodeValue));
}
}
// Process CSS style nodes (assume all style are CSS...)
foreach ($dom->getElementsByTagName('style') as $v) {
$nv=proxyProcessCSS($v->nodeValue);
// Process comment nodes
foreach ($v->childNodes as $cssN) if($cssN->nodeType==XML_COMMENT_NODE) $nv.="\n".proxyProcessCSS($cssN->nodeValue);
$v->nodeValue=$nv;
}
/**
* Insert proxy javascript
*/
$script=$dom->createElement('script');
$script->setAttribute("type","text/javascript");
$scriptContent =";var baseURLProxy=\"".$_ENV['baseURLProxy']."\";\n";
$scriptContent.="var proxyBaseHref=\"".$_ENV['baseHref']."\";\n";
$scriptContent.="var siteHref=new proxyDocumentLocation(\"".$_ENV['baseURL']."\");\n";
$scriptContent.="var proxyDoc=new proxyDocument();\n";
// Send cookies in a javascript var so they can be manipulated in javascript:
// Browse all proxy-stored cookies and determine which ones should be sent to page
$cookies='';
if(isset($_ENV['browserCookies'])) foreach ($_ENV['browserCookies'] as $k=>$v){
// If correct domain and path
if(substr($_ENV['siteDecodedURL']['host'],-strlen($v['domain']))==$v['domain'] && substr(((isset($_ENV['siteDecodedURL']['path']))?$_ENV['siteDecodedURL']['path']:'/'),0,strlen($v['path']))==$v['path']){
// Add cookie to headers (if not secure or https)
if(!$v['secure'] || (isset($_ENV['siteDecodedURL']['protocol']) && $_ENV['siteDecodedURL']['protocol']=='https')) $cookies.='; '.$v['name'].'='.$v['value'];
}
}
$scriptContent.='var proxyCookies="'.str_replace('"','\\"',substr($cookies,2))."\";\n";
$scriptContent.="\n\n\n\n\n/* ------------------------------------------------------------------ */\n\n\n\n\n\n";
$script->nodeValue=file_get_contents(cfAppDocRoot().'/js/proxyScripts.js').$scriptContent;
// Insert into head if a head is found
if($dom->getElementsByTagName('head')->length){
// Insert before first script
if($dom->getElementsByTagName('head')->item(0)->getElementsByTagName('script')->length>0){
$dom->getElementsByTagName('head')->item(0)->insertBefore($script,
$dom->getElementsByTagName('head')->item(0)->getElementsByTagName('script')->item(0));
}
// If no script, insert at head's end
else
$dom->getElementsByTagName('head')->item(0)->appendChild($script);
}
// Insert proxy nodes
if($dom->getElementsByTagName('body')->length){
$newNode=$dom->createElement('div');
$newNode->setAttribute("style","display:none");
$newNode->setAttribute("id","proxyDWDOM");
$dom->getElementsByTagName('body')->item(0)->insertBefore($newNode,$dom->getElementsByTagName('body')->item(0)->firstChild);
$newNode=$dom->createElement('script');
$newNode->setAttribute("type","text/javascript");
$newNode->nodeValue='var proxyDocumentLocationNode=document.getElementById("proxyDocumentLocationNode");';
$dom->getElementsByTagName('body')->item(0)->insertBefore($newNode,$dom->getElementsByTagName('body')->item(0)->firstChild);
$newNode=$dom->createElement('input');
$newNode->setAttribute("style","display:none");
$newNode->setAttribute("id","proxyDocumentLocationNode");
$dom->getElementsByTagName('body')->item(0)->insertBefore($newNode,$dom->getElementsByTagName('body')->item(0)->firstChild);
}
// Workaround : DOM parser bug on <script> tags including other tags (in document.write for example) => base64 decode content
$encoded=preg_replace_callback("/>b64([a-zA-Z0-9\/+]*[=]{0,2})</", "proxyUnprotectJavascriptCB", @$dom->saveHTML());
return $encoded;
//cfVarDump($_SERVER['REQUEST_URI'].' -> '.$_ENV['baseURL']);
//file_put_contents($debugDirectory.'/pageS.html',$body);
//file_put_contents($debugDirectory.'/pageE.html',$encoded);
cfChronoAddPoint('fin encodage');
return;
require_once(INCLUDE_DIR.'Text/Highlighter.php');
?>
<style type="text/css">
.hl-main {font-family: monospace; font-size:13px;background:white}
.hl-gutter { background-color: #CCCCCC; padding-right: 10px;
font-family: monospace; font-size:13px;}
.hl-table {border: solid 1px #000000; }
.hl-default { color: #000000;}
.hl-code { color: #7f7f33; }
.hl-brackets { color: #009966; }
.hl-comment { color: white; background:#AAF}
.hl-quotes { color: #00007F; }
.hl-string { color: #009900; }
.hl-identifier { color: #000000; }
.hl-reserved { color: #0000FF; }
.hl-inlinedoc { color: #EEF; background:#AAF}
.hl-var { color: #CC3300; }
.hl-url { color: #FF0000; text-decoration:underline}
.hl-special { color: #0000FF; }
.hl-number { color: #007F00; }
.hl-inlinetags { color: #FF0000; }
</style>
<div id="proxyBrowser">
<div id="proxyBrowserSource" style="width:100%; border:1px solid #DDD">
<div style="background:#DFD" onclick="if(document.getElementById('proxyBrowserSourceDiv').style.display=='inline') document.getElementById('proxyBrowserSourceDiv').style.display='none'; else document.getElementById('proxyBrowserSourceDiv').style.display='inline'">
<span style="font-weight:bold;font-size:18px"> + SOURCE </span>
</div>
<div id="proxyBrowserSourceDiv" style="display:none">
<?php
$hl =& Text_Highlighter::factory('HTML');
//echo $hl->highlight($body);;
//echo str_replace('<','<',$body);
?>
</div>
</div>
<div id="proxyBrowserEncoded" style="width:100%; border:1px solid #DDD;margin-top:3px">
<div style="background:#FDD" onclick="if(document.getElementById('proxyBrowserEncodedDiv').style.display=='inline') document.getElementById('proxyBrowserEncodedDiv').style.display='none'; else document.getElementById('proxyBrowserEncodedDiv').style.display='inline'">
<span style="font-weight:bold;font-size:18px"> + ENCODED </span>
</div>
<div id="proxyBrowserEncodedDiv" style="display:none">
<?php
$hl =& Text_Highlighter::factory('HTML');
echo $hl->highlight($encoded);
//echo str_replace('<','<',$encoded);
//echo str_replace('<','<br><',$dom->saveHTML());
?>
</div>
</div>
</div>
<?php
}
/** **********************************************************************************************************************************************************
*
* @desc load and process given URL
*
* @param string $url
*
********************************************************************************************************************************************************** */
function proxyProcessPage($decodedURL){
if(!$decodedURL) return ;
// Set proxy settings (if not already set)
proxySetOptions();
//cfDbg(array('URL'=>$decodedURL)+getallheaders());
/**
* Get server-side stored cookies
*/
if(!$_ENV['options']['noCookies']){
$cookiesUpdated=false;
// Get session cookies
$_ENV['browserCookies']=cfRGetVar('sessionCookies');
if(!$_ENV['browserCookies']) $_ENV['browserCookies']=array();
// Add persistent cookies
if(file_exists(cfAppResourceDir().'/persistentCookies.txt')) foreach (unserialize(file_get_contents(cfAppResourceDir().'/persistentCookies.txt')) as $v) $_ENV['browserCookies'][]=$v;
// Clear expired cookies
foreach ($_ENV['browserCookies'] as $k=>$v) if($v['expires']!=='session' && $v['expires']<time()) {
unset($_ENV['browserCookies'][$k]);
$cookiesUpdated=true;
}
}
/*
***************************************************************************************************************************
* WEB BROWSER => PROXY
***************************************************************************************************************************
*/
//if(substr($decodedURL,0,8)=='https://') cfDbg($decodedURL,1);
if(strtolower(substr($decodedURL,0,7))!='http://' && strtolower(substr($decodedURL,0,8))!='https://') $decodedURL='http://'.$decodedURL;
// Parse and store base URL
$_ENV['baseURL']=$decodedURL;
if(!$url=@parse_url($decodedURL)) exit;
$_ENV['siteDecodedURL']=$url;
// Protect LAN and localhost if required by config
if(cfIsOnLAN($url['host']) && !cfRGetVar('allowLocalRequests')) {
require_once(INCLUDE_DIR.'outputFunctions.php');
outDisplayErrorPage(cfCaption('genNoAccess'));
}
$_ENV['siteURLScheme']= ((isset($url['scheme']))?$url['scheme']:((isset($url['port']) && $url['port']==443)?'https':'http'));
$_ENV['siteURLHost']=$_ENV['siteURLScheme'].'://';
if(isset($url['user']) && isset($url['pass'])) $_ENV['siteURLHost'].=$url['user'].':'.$url['pass'].'@';
$_ENV['siteURLHost'].=$url['host'].(isset($url['port'])?':'.$url['port']:'');
if(isset($url['path']) && $url['path']!='/'){
if(substr($url['path'],-1)=='/') $_ENV['siteURLPath']=substr($url['path'],0,strlen($url['path'])-1);
else $_ENV['siteURLPath']=dirname($url['path']);
if($_ENV['siteURLPath']=='\\') $_ENV['siteURLPath']='';
}
else $_ENV['siteURLPath']='';
$_ENV['baseURLGet']=((isset($url['query'])?'?'.$url['query']:''));
// Proxy base URL
if(cfGGetVar('hostName'))
$_ENV['baseURLProxy']=cfGGetVar('hostName');
else{
$_ENV['baseURLProxy']=((isset($_SERVER['HTTPS']))?'https':'http').'://'.$_SERVER['SERVER_ADDR'].':'.$_SERVER['SERVER_PORT'];
}
$_ENV['baseURLProxy']=str_replace('127.0.0.1','localhost',$_ENV['baseURLProxy']).dirname($_SERVER['PHP_SELF']).'/';
// Process cookies received from browser to detect modifications (new/deleted/updated)
if(!$_ENV['options']['noCookies'] && isset($_COOKIE)){
foreach ($_COOKIE as $cookieName=>$cookieValue){
// If this cookie is used by proxy
if(substr($cookieName,0,11)=='proxyCookie') {
$cookiesUpdated=true;
// Get cookie name
$cookieName=substr($cookieName,11);
// Get cookie expiry date and value
list($void,$expires,$cookieValue)=explode('/',$cookieValue,3);
// See if this cookie already exists
foreach ($_ENV['browserCookies'] as $k=>$v){
// If cookie has same name and host and path match, remove
if($v['name']==$cookieName && substr($url['host'],-strlen($v['domain']))==$v['domain'] && substr(((isset($url['path']))?$url['path']:'/'),0,strlen($v['path']))==$v['path']) unset($_ENV['browserCookies'][$k]);
}
// Add it to list
$_ENV['browserCookies'][]=array('name'=>$cookieName,'value'=>$cookieValue,'domain'=>$url['host'],'path'=>'/','expires'=>$expires,'secure'=>false);
}
}
}
/*
***************************************************************************************************************************
* PROXY => SITE
***************************************************************************************************************************
*/
//cfDbg(array('URL:'=>$decodedURL,' '=>' ')+getallheaders(),1);
// Set browser headers
foreach (getallheaders() as $key=>$value) $inHeaders[strtolower($key)]=$value;
unset($inHeaders['host']);
unset($inHeaders['content-length']);
// Remove cookies sent by browser
unset($inHeaders['cookie']);
unset($inHeaders['cookie2']);
// Set cookies
if(!$_ENV['options']['noCookies']) {
$inHeaders['cookie']='';
foreach ($_ENV['browserCookies'] as $k=>$v){
// If matching domain and path
if(substr($url['host'],-strlen($v['domain']))==$v['domain'] && substr(((isset($url['path']))?$url['path']:'/'),0,strlen($v['path']))==$v['path']){
// Add cookie to headers (if not secure or https)
if(!$v['secure'] || (isset($_ENV['siteDecodedURL']['protocol']) && $url['protocol']=='https')) $inHeaders['cookie'].='; '.$v['name'].'='.$v['value'];
}
}
// Remove 1st ";"
if($inHeaders['cookie']) $inHeaders['cookie']=substr($inHeaders['cookie'],1); else unset($inHeaders['cookie']);
}
//if(isset($inHeaders['cookie'])) cfDbg('Cookies envoyΘs au serveur ('.$_ENV['siteURLPath'].'): '.$inHeaders['cookie']);
//unset($inHeaders['accept-encoding']);
unset($inHeaders['te']);
//unset($inHeaders['Content-Type']);
//unset($inHeaders['accept']);
//unset($inHeaders['accept-charset']);
// Process Referer
if($_ENV['options']['noReferer']) unset($inHeaders['referer']);
elseif(isset($inHeaders['referer'])) $inHeaders['referer']=proxyDecodeUrlPHP($inHeaders['referer']);
// Debug only
unset($inHeaders['if-modified-since']);
unset($inHeaders['if-none-match']);
// Close connections between proxy and site
$inHeaders['connection']='Close';
// Identifie as weezo proxy to avoid bypassing weezo IP checks
if(!isset($inHeaders['user-agent'])) $inHeaders['user-agent']='weezoProxy'; else $inHeaders['user-agent'].=' /weezoProxy';
// Process POST request
$POSTDATA='';
if(isset($GLOBALS['HTTP_RAW_POST_DATA']))
// Unknown encoding
$POSTDATA=$GLOBALS['HTTP_RAW_POST_DATA'];
elseif (isset($_POST) && count($_POST)){
// multipart/form-data
if(isset($inHeaders['content-type']) && stripos($inHeaders['content-type'],'multipart/form-data')!==false){
if(stripos($inHeaders['content-type'],'boundary=')!==false){
$boundary=substr($inHeaders['content-type'],stripos($inHeaders['content-type'],'boundary=')+9);
}
else {
$boundary='----------ek8VX07YznAePPdwJSbq9d';
$inHeaders['content-type']='multipart/form-data; '.$boundary;
}
foreach ($_POST as $key=>$value){
$POSTDATA.='--'.$boundary."\r\nContent-Disposition: form-data; name=\"".$key."\"\r\n\r\n".$value."\r\n";
}
$POSTDATA.='--'.$boundary.'--';
}
// Assume application/x-www-form-urlencoded
else{
foreach ($_POST as $key=>$value) $POSTDATA.='&'.urlencode($key).'='.urlencode($value);
$POSTDATA=substr($POSTDATA,1);
}
}
elseif (isset($inHeaders['content-type'])) unset($inHeaders['content-type']);
if($POSTDATA) $inHeaders['content-length']=strlen($POSTDATA);
cfChronoAddPoint('start Loading page');
foreach ($inHeaders as $k=>$v){$ucHeaders[str_replace(' ','-',ucfirst(str_replace('-',' ',$k)))]=$v;}
$inHeaders=$ucHeaders;
//cfDbg($inHeaders,1);
// Open handle on document
if(!($handle=cfSocketHTTPRequest($decodedURL,4,false,$err,$void,false,true,$inHeaders,$POSTDATA))) {
//cfDbg('No socket connection to '.$decodedURL,1);
return null;
}
/*
***************************************************************************************************************************
* SITE => PROXY
***************************************************************************************************************************
*/
// Read Headers
$data=''; $body='';
while(!feof($handle) && (!strpos($data,"\r\n\r\n")) && (!strpos($data,"\n\r\n\r"))) $data .= @fread($handle, 5120);
cfChronoAddPoint('done Loading header');
// Parse Header
$fullStatus='';cfParseHTTPResponse($data,$status,$body,$headers,$fullStatus);
//cfDbg('RETURNED HEADERS');
//cfDbg($fullStatus);
//cfDbg($headers);
// Flatten headers (other than set-cookie)
foreach ($headers as $k=>$v) if(is_array($v) && $k!='set-cookie') $headers[$k]=$v[count($v)-1];
// Get document's mime type
if(strpos($decodedURL,'?')) $path=substr($decodedURL,0,strpos($decodedURL,'?')); else $path=$decodedURL;
if(isset($headers['mime-type'])) $mimeType=$headers['mime-type'];
elseif (isset($headers['content-type'])) $mimeType=((strpos($headers['content-type'],';')?substr($headers['content-type'],0,strpos($headers['content-type'],';')):$headers['content-type']));
else{
require_once(INCLUDE_DIR.'mime_type.php');
$mimeType=mimeType($path);
}
if(!$mimeType) $mimeType=='text/html'; // If mime type not found, treat as HTML
// Correct js mime type
if(cfFileExtension($path)=='js' || strpos($_SERVER['REQUEST_URI'],'/eourl/js')) {
if(isset($headers['content-type'])) $headers['content-type']=str_ireplace($mimeType,'text/javascript',$headers['content-type']);
$mimeType='text/javascript';
}
// Correct css mime type
if(strpos($_SERVER['REQUEST_URI'],'/eourl/css')) $mimeType='text/css';
// Process server-sent cookies
if(isset($headers['set-cookie']) && !$_ENV['options']['noCookies']){
if(!is_array($headers['set-cookie'])) $headers['set-cookie']=array(0=>$headers['set-cookie']);
//if(count($headers['set-cookie'])>5) cfDbg('SET '.count($headers['set-cookie']).' cookies !!!',1);
foreach ($headers['set-cookie'] as $setCookieHeader){
//cfDbg('set-cookie header: '.$setCookieHeader);
$setCookie=explode(';',$setCookieHeader);
@list($cookieName,$cookieValue)=explode('=',reset($setCookie),2);
// If a cookie is sent
if($cookieName && $cookieValue){
if(!$_ENV['options']['noCookies'] && isset($_COOKIE)){
// Set default cookie parameters
$cookieDomain=array_reverse(explode('.',$url['host']));
if(is_numeric($cookieDomain[0])) $cookieDomain=$url['host'];
elseif ($cookieDomain[0]=='localhost') $cookieDomain='127.0.0.1';
elseif(count($cookieDomain)==1) $cookieDomain=$cookieDomain[0];
else $cookieDomain='.'.$cookieDomain[1].'.'.$cookieDomain[0];
$cookiePath='/';
$cookieExpires='session';
$cookieSecure=false;
// Get set-cookie parameters
foreach ($setCookie as $v){
@list($key,$value)=explode('=',$v,2);
$key=trim($key);$value=trim($value);
if($key=='expires' && $value!='session') $cookieExpires=@strtotime($value);
elseif($key=='domain') $cookieDomain=$value;
elseif($key=='path') $cookiePath=$value;
elseif($key=='secure') $cookieSecure=true;
}
// Remove this cookie from proxy cookies list (if present)
foreach ($_ENV['browserCookies'] as $k=>$v)
if($v['name']==$cookieName && $v['domain']==$cookieDomain && $v['path']==$cookiePath) unset($_ENV['browserCookies'][$k]);
// Integrate this new cookie in proxy cookies list
$_ENV['browserCookies'][]=array('name'=>$cookieName,'value'=>$cookieValue,'domain'=>$cookieDomain,'path'=>$cookiePath,'secure'=>$cookieSecure,'expires'=>$cookieExpires);
$cookiesUpdated=true;
}
}
}
}
// Save proxy-stored cookies
if(!$_ENV['options']['noCookies'] && $cookiesUpdated) {
// Separate session cookies and persistent cookies
$sessionCookies=array();
$persistentCookies=array();
foreach ($_ENV['browserCookies'] as $cookie){
if($cookie['expires']=='session') $sessionCookies[]=$cookie; else $persistentCookies[]=$cookie;
}
// Save session cookies in a session var
if(count($sessionCookies)){
wSession_start();
cfRSetVar('sessionCookies',$sessionCookies);
wSession_write_close();
}
// Save persistent cookies in a file
if(count($persistentCookies)) file_put_contents(cfAppResourceDir().'/persistentCookies.txt',serialize($persistentCookies));
}
/*
***************************************************************************************************************************
* PROXY => WEB BROWSER
***************************************************************************************************************************
*/
// Debug
$debugDirectory=cfRGetVar('debugDirectory');
$debugExt=cfRGetVar('debugExt');
$pathToFile=strtr($path,'<>?/\\:*"|','---------');
// Don't send content-length now
if(isset($headers['content-length'])){
$contentLength=$headers['content-length'];
unset($headers['content-length']);
}
else $contentLength=false;
// Process body
switch ($mimeType) {
// HTML
case 'text/plain':
case 'text/php':
case 'text/asp':
case 'text/aspx':
case 'text/html':
case 'text/htm':
case 'text/xml':
// Read
stream_set_blocking($handle,1); while(!feof($handle)) $body.=@fread($handle, 8192); fclose($handle);
// gzip decode
if (isset($headers['content-encoding'])&& ($headers['content-encoding']=='gzip' || $headers['content-encoding']=='x-gzip')) $body=gzdecode($body);
// unset unneeded headers an send headers
unset($headers['content-length']);
unset($headers['content-encoding']);
proxySendHeadersToBrowser($fullStatus, $headers,false);
// Clean BOM and reencode page
$h[0]=ord(substr($body,0,1));
$h[1]=ord(substr($body,1,1));
$h[2]=ord(substr($body,2,1));
$h[3]=ord(substr($body,3,1));
if($h[0]==239 && $h[1]==187 && $h[2]==191) $body=mb_convert_encoding(substr($body,3), 'HTML-ENTITIES', "UTF-8");
elseif ($h[0]==0 && $h[1]==0 && $h[2]==255 && $h[3]==254) $body=mb_convert_encoding(substr($body,4), 'HTML-ENTITIES', "UTF-32BE");
elseif ($h[0]==255 && $h[1]==254 && $h[2]==0 && $h[3]==0) $body=mb_convert_encoding(substr($body,4), 'HTML-ENTITIES', "UTF-32LE");
elseif ($h[0]==255 && $h[1]==254) $body=mb_convert_encoding(substr($body,2), 'HTML-ENTITIES', "UTF-16LE");
elseif ($h[0]==254 && $h[1]==255) $body=mb_convert_encoding(substr($body,2), 'HTML-ENTITIES', "UTF-16BE");
elseif ($h[0]==43 && $h[1]==47 && $h[1]==118) $body=mb_convert_encoding(substr($body,4), 'HTML-ENTITIES', "UTF-7");
// Debug - source
//$debugExt='html';
//$debugDirectory='c:/P1/temp/proxy';
if($debugDirectory && (strpos($debugExt,'html') || strpos($debugExt,'*'))) {@unlink($debugDirectory.'/html-'.$pathToFile.'-src.html'); cfAppendTextToFile($body,$debugDirectory.'/html-'.basename($path).'-src.html',false);}
// Send processed HTML code
if($mimeType!='text/xml') $body=proxyProcessHTML($body,isset($headers['content-type'])?$headers['content-type']:false);
echo $body;
// Debug - encoded
if($debugDirectory && (strpos($debugExt,'html') || strpos($debugExt,'*'))) {@unlink($debugDirectory.'/html-'.$pathToFile.'-dest.html'); cfAppendTextToFile($body,$debugDirectory.'/html-'.basename($path).'-dest.html',false);}
break;
// Javascript
case 'text/javascript':
case 'application/x-javascript':
// Read
stream_set_blocking($handle,1); while(!feof($handle)) $body.=@fread($handle, 8192); fclose($handle);
// gzip decode
if (isset($headers['content-encoding'])&& ($headers['content-encoding']=='gzip' || $headers['content-encoding']=='x-gzip')) $body=gzdecode($body);
// unset unneeded headers an send headers
unset($headers['content-length']);
unset($headers['content-encoding']);
proxySendHeadersToBrowser($fullStatus, $headers);
// Debug - log source
if($debugDirectory && (strpos($debugExt,'js') || strpos($debugExt,'*'))) {@unlink($debugDirectory.'/js-'.$pathToFile.'-src.js'); cfAppendTextToFile($body,$debugDirectory.'/js-'.basename($path).'-src.js',false);}
// Send processed javascript code
$out= proxyProcessJavascript($body);
echo $out;
// Debug - log destination
if($debugDirectory && (strpos($debugExt,'js') || strpos($debugExt,'*'))) {@unlink($debugDirectory.'/js-'.$pathToFile.'-src.js'); cfAppendTextToFile($body,$debugDirectory.'/js-'.basename($path).'-src.js',false);}
break;
// CSS
case 'text/css':
// Read
stream_set_blocking($handle,1); while(!feof($handle)) $body.=@fread($handle, 8192); fclose($handle);
// gzip decode
if (isset($headers['content-encoding'])&& ($headers['content-encoding']=='gzip' || $headers['content-encoding']=='x-gzip')) $body=gzdecode($body);
// unset unneeded headers an send headers
unset($headers['content-length']);
unset($headers['content-encoding']);
proxySendHeadersToBrowser($fullStatus, $headers);
// Debug - log source
if($debugDirectory && (strpos($debugExt,'css') || strpos($debugExt,'*'))) {@unlink($debugDirectory.'/css-'.$pathToFile.'-src.css'); cfAppendTextToFile($body,$debugDirectory.'/css-'.basename($path).'-src.css',false);}
// Send processed CSS code
echo proxyProcessCSS($body);
// Debug - log destination
if($debugDirectory && (strpos($debugExt,'css') || strpos($debugExt,'*'))) {@unlink($debugDirectory.'/css-'.$pathToFile.'-dest.css'); cfAppendTextToFile($body,$debugDirectory.'/css-dest-'.basename($path).'-dest.css',false);}
break;
// Other : stream to output
default:
// Debug - log streamed data
$fh=null;
if($debugDirectory && (strpos($debugExt,'*') || strpos($debugExt,cfFileExtension($path)))){
@unlink($debugDirectory.'/untouched-'.$pathToFile);
$fh=fopen($debugDirectory.'/untouched-'.$pathToFile,'wb');
}
if (false && isset($headers['content-encoding'])&& ($headers['content-encoding']=='gzip' || $headers['content-encoding']=='x-gzip')) {
while(!feof($handle)) $body.=@fread($handle, 8192); fclose($handle);
$body=gzdecode($body);
if($sendHeaders) header('Content-Length: '.strlen($body));
echo $body;
// Debug
if($fh) fwrite($fh,$body);
}
else{
proxySendHeadersToBrowser($fullStatus, $headers);
echo $body;
// Debug
if($fh) {
fwrite($fh,$body);
while(!feof($handle)) {
$body=@fread($handle, 8192);
fwrite($fh,$body);
echo $body;
}
}
else while(!feof($handle)) echo @fread($handle, 8192);
fclose($handle);
}
// Close debug file
if($fh) fclose($fh);
}
}
?>